home *** CD-ROM | disk | FTP | other *** search
/ PC PowerPlay 22 / PCPP #22.iso / Quake2 / q2source_12_11 / utils3 / qe4 / lbmlib.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-09-17  |  16.4 KB  |  814 lines

  1. // lbmlib.c
  2.  
  3. #include "cmdlib.h"
  4. #include "lbmlib.h"
  5.  
  6.  
  7.  
  8. /*
  9. ============================================================================
  10.  
  11.                         LBM STUFF
  12.  
  13. ============================================================================
  14. */
  15.  
  16.  
  17. typedef unsigned char    UBYTE;
  18. //conflicts with windows typedef short            WORD;
  19. typedef unsigned short    UWORD;
  20. typedef long            LONG;
  21.  
  22. typedef enum
  23. {
  24.     ms_none,
  25.     ms_mask,
  26.     ms_transcolor,
  27.     ms_lasso
  28. } mask_t;
  29.  
  30. typedef enum
  31. {
  32.     cm_none,
  33.     cm_rle1
  34. } compress_t;
  35.  
  36. typedef struct
  37. {
  38.     UWORD        w,h;
  39.     short        x,y;
  40.     UBYTE        nPlanes;
  41.     UBYTE        masking;
  42.     UBYTE        compression;
  43.     UBYTE        pad1;
  44.     UWORD        transparentColor;
  45.     UBYTE        xAspect,yAspect;
  46.     short        pageWidth,pageHeight;
  47. } bmhd_t;
  48.  
  49. extern    bmhd_t    bmhd;                        // will be in native byte order
  50.  
  51.  
  52.  
  53. #define FORMID ('F'+('O'<<8)+((int)'R'<<16)+((int)'M'<<24))
  54. #define ILBMID ('I'+('L'<<8)+((int)'B'<<16)+((int)'M'<<24))
  55. #define PBMID  ('P'+('B'<<8)+((int)'M'<<16)+((int)' '<<24))
  56. #define BMHDID ('B'+('M'<<8)+((int)'H'<<16)+((int)'D'<<24))
  57. #define BODYID ('B'+('O'<<8)+((int)'D'<<16)+((int)'Y'<<24))
  58. #define CMAPID ('C'+('M'<<8)+((int)'A'<<16)+((int)'P'<<24))
  59.  
  60.  
  61. bmhd_t  bmhd;
  62.  
  63. int    Align (int l)
  64. {
  65.     if (l&1)
  66.         return l+1;
  67.     return l;
  68. }
  69.  
  70.  
  71.  
  72. /*
  73. ================
  74. LBMRLEdecompress
  75.  
  76. Source must be evenly aligned!
  77. ================
  78. */
  79. byte  *LBMRLEDecompress (byte *source,byte *unpacked, int bpwidth)
  80. {
  81.     int     count;
  82.     byte    b,rept;
  83.  
  84.     count = 0;
  85.  
  86.     do
  87.     {
  88.         rept = *source++;
  89.  
  90.         if (rept > 0x80)
  91.         {
  92.             rept = (rept^0xff)+2;
  93.             b = *source++;
  94.             memset(unpacked,b,rept);
  95.             unpacked += rept;
  96.         }
  97.         else if (rept < 0x80)
  98.         {
  99.             rept++;
  100.             memcpy(unpacked,source,rept);
  101.             unpacked += rept;
  102.             source += rept;
  103.         }
  104.         else
  105.             rept = 0;               // rept of 0x80 is NOP
  106.  
  107.         count += rept;
  108.  
  109.     } while (count<bpwidth);
  110.  
  111.     if (count>bpwidth)
  112.         Error ("Decompression exceeded width!\n");
  113.  
  114.  
  115.     return source;
  116. }
  117.  
  118.  
  119. /*
  120. =================
  121. LoadLBM
  122. =================
  123. */
  124. void LoadLBM (char *filename, byte **picture, byte **palette)
  125. {
  126.     byte    *LBMbuffer, *picbuffer, *cmapbuffer;
  127.     int             y;
  128.     byte    *LBM_P, *LBMEND_P;
  129.     byte    *pic_p;
  130.     byte    *body_p;
  131.  
  132.     int    formtype,formlength;
  133.     int    chunktype,chunklength;
  134.  
  135. // qiet compiler warnings
  136.     picbuffer = NULL;
  137.     cmapbuffer = NULL;
  138.  
  139. //
  140. // load the LBM
  141. //
  142.     LoadFile (filename, (void **)&LBMbuffer);
  143.  
  144. //
  145. // parse the LBM header
  146. //
  147.     LBM_P = LBMbuffer;
  148.     if ( *(int *)LBMbuffer != LittleLong(FORMID) )
  149.        Error ("No FORM ID at start of file!\n");
  150.  
  151.     LBM_P += 4;
  152.     formlength = BigLong( *(int *)LBM_P );
  153.     LBM_P += 4;
  154.     LBMEND_P = LBM_P + Align(formlength);
  155.  
  156.     formtype = LittleLong(*(int *)LBM_P);
  157.  
  158.     if (formtype != ILBMID && formtype != PBMID)
  159.         Error ("Unrecognized form type: %c%c%c%c\n", formtype&0xff
  160.         ,(formtype>>8)&0xff,(formtype>>16)&0xff,(formtype>>24)&0xff);
  161.  
  162.     LBM_P += 4;
  163.  
  164. //
  165. // parse chunks
  166. //
  167.  
  168.     while (LBM_P < LBMEND_P)
  169.     {
  170.         chunktype = LBM_P[0] + (LBM_P[1]<<8) + (LBM_P[2]<<16) + (LBM_P[3]<<24);
  171.         LBM_P += 4;
  172.         chunklength = LBM_P[3] + (LBM_P[2]<<8) + (LBM_P[1]<<16) + (LBM_P[0]<<24);
  173.         LBM_P += 4;
  174.  
  175.         switch ( chunktype )
  176.         {
  177.         case BMHDID:
  178.             memcpy (&bmhd,LBM_P,sizeof(bmhd));
  179.             bmhd.w = BigShort(bmhd.w);
  180.             bmhd.h = BigShort(bmhd.h);
  181.             bmhd.x = BigShort(bmhd.x);
  182.             bmhd.y = BigShort(bmhd.y);
  183.             bmhd.pageWidth = BigShort(bmhd.pageWidth);
  184.             bmhd.pageHeight = BigShort(bmhd.pageHeight);
  185.             break;
  186.  
  187.         case CMAPID:
  188.             cmapbuffer = malloc (768);
  189.             memset (cmapbuffer, 0, 768);
  190.             memcpy (cmapbuffer, LBM_P, chunklength);
  191.             break;
  192.  
  193.         case BODYID:
  194.             body_p = LBM_P;
  195.  
  196.             pic_p = picbuffer = malloc (bmhd.w*bmhd.h);
  197.             if (formtype == PBMID)
  198.             {
  199.             //
  200.             // unpack PBM
  201.             //
  202.                 for (y=0 ; y<bmhd.h ; y++, pic_p += bmhd.w)
  203.                 {
  204.                     if (bmhd.compression == cm_rle1)
  205.                         body_p = LBMRLEDecompress ((byte *)body_p
  206.                         , pic_p , bmhd.w);
  207.                     else if (bmhd.compression == cm_none)
  208.                     {
  209.                         memcpy (pic_p,body_p,bmhd.w);
  210.                         body_p += Align(bmhd.w);
  211.                     }
  212.                 }
  213.  
  214.             }
  215.             else
  216.             {
  217.             //
  218.             // unpack ILBM
  219.             //
  220.                 Error ("%s is an interlaced LBM, not packed", filename);
  221.             }
  222.             break;
  223.         }
  224.  
  225.         LBM_P += Align(chunklength);
  226.     }
  227.  
  228.     free (LBMbuffer);
  229.  
  230.     *picture = picbuffer;
  231.  
  232.     if (palette)
  233.         *palette = cmapbuffer;
  234. }
  235.  
  236.  
  237. /*
  238. ============================================================================
  239.  
  240.                             WRITE LBM
  241.  
  242. ============================================================================
  243. */
  244.  
  245. /*
  246. ==============
  247. WriteLBMfile
  248. ==============
  249. */
  250. void WriteLBMfile (char *filename, byte *data,
  251.                    int width, int height, byte *palette)
  252. {
  253.     byte    *lbm, *lbmptr;
  254.     int    *formlength, *bmhdlength, *cmaplength, *bodylength;
  255.     int    length;
  256.     bmhd_t  basebmhd;
  257.  
  258.     lbm = lbmptr = malloc (width*height+1000);
  259.  
  260. //
  261. // start FORM
  262. //
  263.     *lbmptr++ = 'F';
  264.     *lbmptr++ = 'O';
  265.     *lbmptr++ = 'R';
  266.     *lbmptr++ = 'M';
  267.  
  268.     formlength = (int*)lbmptr;
  269.     lbmptr+=4;                      // leave space for length
  270.  
  271.     *lbmptr++ = 'P';
  272.     *lbmptr++ = 'B';
  273.     *lbmptr++ = 'M';
  274.     *lbmptr++ = ' ';
  275.  
  276. //
  277. // write BMHD
  278. //
  279.     *lbmptr++ = 'B';
  280.     *lbmptr++ = 'M';
  281.     *lbmptr++ = 'H';
  282.     *lbmptr++ = 'D';
  283.  
  284.     bmhdlength = (int *)lbmptr;
  285.     lbmptr+=4;                      // leave space for length
  286.  
  287.     memset (&basebmhd,0,sizeof(basebmhd));
  288.     basebmhd.w = BigShort((short)width);
  289.     basebmhd.h = BigShort((short)height);
  290.     basebmhd.nPlanes = 8;
  291.     basebmhd.xAspect = 5;
  292.     basebmhd.yAspect = 6;
  293.     basebmhd.pageWidth = BigShort((short)width);
  294.     basebmhd.pageHeight = BigShort((short)height);
  295.  
  296.     memcpy (lbmptr,&basebmhd,sizeof(basebmhd));
  297.     lbmptr += sizeof(basebmhd);
  298.  
  299.     length = lbmptr-(byte *)bmhdlength-4;
  300.     *bmhdlength = BigLong(length);
  301.     if (length&1)
  302.         *lbmptr++ = 0;          // pad chunk to even offset
  303.  
  304. //
  305. // write CMAP
  306. //
  307.     *lbmptr++ = 'C';
  308.     *lbmptr++ = 'M';
  309.     *lbmptr++ = 'A';
  310.     *lbmptr++ = 'P';
  311.  
  312.     cmaplength = (int *)lbmptr;
  313.     lbmptr+=4;                      // leave space for length
  314.  
  315.     memcpy (lbmptr,palette,768);
  316.     lbmptr += 768;
  317.  
  318.     length = lbmptr-(byte *)cmaplength-4;
  319.     *cmaplength = BigLong(length);
  320.     if (length&1)
  321.         *lbmptr++ = 0;          // pad chunk to even offset
  322.  
  323. //
  324. // write BODY
  325. //
  326.     *lbmptr++ = 'B';
  327.     *lbmptr++ = 'O';
  328.     *lbmptr++ = 'D';
  329.     *lbmptr++ = 'Y';
  330.  
  331.     bodylength = (int *)lbmptr;
  332.     lbmptr+=4;                      // leave space for length
  333.  
  334.     memcpy (lbmptr,data,width*height);
  335.     lbmptr += width*height;
  336.  
  337.     length = lbmptr-(byte *)bodylength-4;
  338.     *bodylength = BigLong(length);
  339.     if (length&1)
  340.         *lbmptr++ = 0;          // pad chunk to even offset
  341.  
  342. //
  343. // done
  344. //
  345.     length = lbmptr-(byte *)formlength-4;
  346.     *formlength = BigLong(length);
  347.     if (length&1)
  348.         *lbmptr++ = 0;          // pad chunk to even offset
  349.  
  350. //
  351. // write output file
  352. //
  353.     SaveFile (filename, lbm, lbmptr-lbm);
  354.     free (lbm);
  355. }
  356.  
  357.  
  358. /*
  359. ============================================================================
  360.  
  361. LOAD PCX
  362.  
  363. ============================================================================
  364. */
  365.  
  366. typedef struct
  367. {
  368.     char    manufacturer;
  369.     char    version;
  370.     char    encoding;
  371.     char    bits_per_pixel;
  372.     unsigned short    xmin,ymin,xmax,ymax;
  373.     unsigned short    hres,vres;
  374.     unsigned char    palette[48];
  375.     char    reserved;
  376.     char    color_planes;
  377.     unsigned short    bytes_per_line;
  378.     unsigned short    palette_type;
  379.     char    filler[58];
  380.     unsigned char    data;            // unbounded
  381. } pcx_t;
  382.  
  383.  
  384. /*
  385. ==============
  386. LoadPCX
  387. ==============
  388. */
  389. void LoadPCX (char *filename, byte **pic, byte **palette, int *width, int *height)
  390. {
  391.     byte    *raw;
  392.     pcx_t    *pcx;
  393.     int        x, y;
  394.     int        len;
  395.     int        dataByte, runLength;
  396.     byte    *out, *pix;
  397.  
  398.     if (pic)
  399.         *pic = NULL;
  400.     if (palette)
  401.         *palette = NULL;
  402.     if (width)
  403.         *width = 0;
  404.     if (height)
  405.         *height = 0;
  406.  
  407.     //
  408.     // load the file
  409.     //
  410.     len = LoadFile (filename, (void **)&raw);
  411.     if (len == -1)
  412.         return;
  413.  
  414.     //
  415.     // parse the PCX file
  416.     //
  417.     pcx = (pcx_t *)raw;
  418.     raw = &pcx->data;
  419.  
  420.     pcx->xmin = LittleShort(pcx->xmin);
  421.     pcx->ymin = LittleShort(pcx->ymin);
  422.     pcx->xmax = LittleShort(pcx->xmax);
  423.     pcx->ymax = LittleShort(pcx->ymax);
  424.     pcx->hres = LittleShort(pcx->hres);
  425.     pcx->vres = LittleShort(pcx->vres);
  426.     pcx->bytes_per_line = LittleShort(pcx->bytes_per_line);
  427.     pcx->palette_type = LittleShort(pcx->palette_type);
  428.  
  429.     if (pcx->manufacturer != 0x0a
  430.         || pcx->version != 5
  431.         || pcx->encoding != 1
  432.         || pcx->bits_per_pixel != 8
  433.         || pcx->xmax >= 640
  434.         || pcx->ymax >= 480)
  435.         Error ("Bad pcx file %s", filename);
  436.     
  437.     if (palette)
  438.     {
  439.         *palette = malloc(768);
  440.         memcpy (*palette, (byte *)pcx + len - 768, 768);
  441.     }
  442.  
  443.     if (width)
  444.         *width = pcx->xmax+1;
  445.     if (height)
  446.         *height = pcx->ymax+1;
  447.  
  448.     if (!pic)
  449.         return;
  450.  
  451.     out = malloc ( (pcx->ymax+1) * (pcx->xmax+1) );
  452.     if (!out)
  453.         Error ("Skin_Cache: couldn't allocate");
  454.  
  455.     *pic = out;
  456.  
  457.     pix = out;
  458.  
  459.     for (y=0 ; y<=pcx->ymax ; y++, pix += pcx->xmax+1)
  460.     {
  461.         for (x=0 ; x<=pcx->xmax ; )
  462.         {
  463.             dataByte = *raw++;
  464.  
  465.             if((dataByte & 0xC0) == 0xC0)
  466.             {
  467.                 runLength = dataByte & 0x3F;
  468.                 dataByte = *raw++;
  469.             }
  470.             else
  471.                 runLength = 1;
  472.  
  473.             while(runLength-- > 0)
  474.                 pix[x++] = dataByte;
  475.         }
  476.  
  477.     }
  478.  
  479.     if ( raw - (byte *)pcx > len)
  480.         Error ("PCX file %s was malformed", filename);
  481.  
  482.     free (pcx);
  483. }
  484.  
  485. /* 
  486. ============== 
  487. WritePCXfile 
  488. ============== 
  489. */ 
  490. void WritePCXfile (char *filename, byte *data, 
  491.                    int width, int height, byte *palette) 
  492. {
  493.     int        i, j, length;
  494.     pcx_t    *pcx;
  495.     byte        *pack;
  496.       
  497.     pcx = malloc (width*height*2+1000);
  498.     memset (pcx, 0, sizeof(*pcx));
  499.  
  500.     pcx->manufacturer = 0x0a;    // PCX id
  501.     pcx->version = 5;            // 256 color
  502.      pcx->encoding = 1;        // uncompressed
  503.     pcx->bits_per_pixel = 8;        // 256 color
  504.     pcx->xmin = 0;
  505.     pcx->ymin = 0;
  506.     pcx->xmax = LittleShort((short)(width-1));
  507.     pcx->ymax = LittleShort((short)(height-1));
  508.     pcx->hres = LittleShort((short)width);
  509.     pcx->vres = LittleShort((short)height);
  510.     pcx->color_planes = 1;        // chunky image
  511.     pcx->bytes_per_line = LittleShort((short)width);
  512.     pcx->palette_type = LittleShort(2);        // not a grey scale
  513.  
  514.     // pack the image
  515.     pack = &pcx->data;
  516.     
  517.     for (i=0 ; i<height ; i++)
  518.     {
  519.         for (j=0 ; j<width ; j++)
  520.         {
  521.             if ( (*data & 0xc0) != 0xc0)
  522.                 *pack++ = *data++;
  523.             else
  524.             {
  525.                 *pack++ = 0xc1;
  526.                 *pack++ = *data++;
  527.             }
  528.         }
  529.     }
  530.             
  531.     // write the palette
  532.     *pack++ = 0x0c;    // palette ID byte
  533.     for (i=0 ; i<768 ; i++)
  534.         *pack++ = *palette++;
  535.         
  536. // write output file 
  537.     length = pack - (byte *)pcx;
  538.     SaveFile (filename, pcx, length);
  539.  
  540.     free (pcx);
  541.  
  542.  
  543. /*
  544. ============================================================================
  545.  
  546. LOAD IMAGE
  547.  
  548. ============================================================================
  549. */
  550.  
  551. /*
  552. ==============
  553. Load256Image
  554.  
  555. Will load either an lbm or pcx, depending on extension.
  556. Any of the return pointers can be NULL if you don't want them.
  557. ==============
  558. */
  559. void Load256Image (char *name, byte **pixels, byte **palette,
  560.                    int *width, int *height)
  561. {
  562.     char    ext[128];
  563.  
  564.     ExtractFileExtension (name, ext);
  565.     if (!Q_strcasecmp (ext, "lbm"))
  566.     {
  567.         LoadLBM (name, pixels, palette);
  568.         if (width)
  569.             *width = bmhd.w;
  570.         if (height)
  571.             *height = bmhd.h;
  572.     }
  573.     else if (!Q_strcasecmp (ext, "pcx"))
  574.     {
  575.         LoadPCX (name, pixels, palette, width, height);
  576.     }
  577.     else
  578.         Error ("%s doesn't have a known image extension", name);
  579. }
  580.  
  581.  
  582. /*
  583. ==============
  584. Save256Image
  585.  
  586. Will save either an lbm or pcx, depending on extension.
  587. ==============
  588. */
  589. void Save256Image (char *name, byte *pixels, byte *palette,
  590.                    int width, int height)
  591. {
  592.     char    ext[128];
  593.  
  594.     ExtractFileExtension (name, ext);
  595.     if (!Q_strcasecmp (ext, "lbm"))
  596.     {
  597.         WriteLBMfile (name, pixels, width, height, palette);
  598.     }
  599.     else if (!Q_strcasecmp (ext, "pcx"))
  600.     {
  601.         WritePCXfile (name, pixels, width, height, palette);
  602.     }
  603.     else
  604.         Error ("%s doesn't have a known image extension", name);
  605. }
  606.  
  607.  
  608.  
  609.  
  610. /*
  611. ============================================================================
  612.  
  613. TARGA IMAGE
  614.  
  615. ============================================================================
  616. */
  617.  
  618. typedef struct _TargaHeader {
  619.     unsigned char     id_length, colormap_type, image_type;
  620.     unsigned short    colormap_index, colormap_length;
  621.     unsigned char    colormap_size;
  622.     unsigned short    x_origin, y_origin, width, height;
  623.     unsigned char    pixel_size, attributes;
  624. } TargaHeader;
  625.  
  626. int fgetLittleShort (FILE *f)
  627. {
  628.     byte    b1, b2;
  629.  
  630.     b1 = fgetc(f);
  631.     b2 = fgetc(f);
  632.  
  633.     return (short)(b1 + b2*256);
  634. }
  635.  
  636. int fgetLittleLong (FILE *f)
  637. {
  638.     byte    b1, b2, b3, b4;
  639.  
  640.     b1 = fgetc(f);
  641.     b2 = fgetc(f);
  642.     b3 = fgetc(f);
  643.     b4 = fgetc(f);
  644.  
  645.     return b1 + (b2<<8) + (b3<<16) + (b4<<24);
  646. }
  647.  
  648.  
  649. /*
  650. =============
  651. LoadTGA
  652. =============
  653. */
  654. void LoadTGA (char *name, byte **pixels, int *width, int *height)
  655. {
  656.     int                columns, rows, numPixels;
  657.     byte            *pixbuf;
  658.     int                row, column;
  659.     FILE            *fin;
  660.     byte            *targa_rgba;
  661.     TargaHeader        targa_header;
  662.  
  663.     fin = fopen (name, "rb");
  664.     if (!fin)
  665.         Error ("Couldn't read %s", name);
  666.  
  667.     targa_header.id_length = fgetc(fin);
  668.     targa_header.colormap_type = fgetc(fin);
  669.     targa_header.image_type = fgetc(fin);
  670.     
  671.     targa_header.colormap_index = fgetLittleShort(fin);
  672.     targa_header.colormap_length = fgetLittleShort(fin);
  673.     targa_header.colormap_size = fgetc(fin);
  674.     targa_header.x_origin = fgetLittleShort(fin);
  675.     targa_header.y_origin = fgetLittleShort(fin);
  676.     targa_header.width = fgetLittleShort(fin);
  677.     targa_header.height = fgetLittleShort(fin);
  678.     targa_header.pixel_size = fgetc(fin);
  679.     targa_header.attributes = fgetc(fin);
  680.  
  681.     if (targa_header.image_type!=2 
  682.         && targa_header.image_type!=10) 
  683.         Error ("LoadTGA: Only type 2 and 10 targa RGB images supported\n");
  684.  
  685.     if (targa_header.colormap_type !=0 
  686.         || (targa_header.pixel_size!=32 && targa_header.pixel_size!=24))
  687.         Error ("Texture_LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n");
  688.  
  689.     columns = targa_header.width;
  690.     rows = targa_header.height;
  691.     numPixels = columns * rows;
  692.  
  693.     if (width)
  694.         *width = columns;
  695.     if (height)
  696.         *height = rows;
  697.     targa_rgba = malloc(numPixels*4);
  698.     *pixels = targa_rgba;
  699.  
  700.     if (targa_header.id_length != 0)
  701.         fseek(fin, targa_header.id_length, SEEK_CUR);  // skip TARGA image comment
  702.     
  703.     if (targa_header.image_type==2) {  // Uncompressed, RGB images
  704.         for(row=rows-1; row>=0; row--) {
  705.             pixbuf = targa_rgba + row*columns*4;
  706.             for(column=0; column<columns; column++) {
  707.                 unsigned char red,green,blue,alphabyte;
  708.                 switch (targa_header.pixel_size) {
  709.                     case 24:
  710.                             
  711.                             blue = getc(fin);
  712.                             green = getc(fin);
  713.                             red = getc(fin);
  714.                             *pixbuf++ = red;
  715.                             *pixbuf++ = green;
  716.                             *pixbuf++ = blue;
  717.                             *pixbuf++ = 255;
  718.                             break;
  719.                     case 32:
  720.                             blue = getc(fin);
  721.                             green = getc(fin);
  722.                             red = getc(fin);
  723.                             alphabyte = getc(fin);
  724.                             *pixbuf++ = red;
  725.                             *pixbuf++ = green;
  726.                             *pixbuf++ = blue;
  727.                             *pixbuf++ = alphabyte;
  728.                             break;
  729.                 }
  730.             }
  731.         }
  732.     }
  733.     else if (targa_header.image_type==10) {   // Runlength encoded RGB images
  734.         unsigned char red,green,blue,alphabyte,packetHeader,packetSize,j;
  735.         for(row=rows-1; row>=0; row--) {
  736.             pixbuf = targa_rgba + row*columns*4;
  737.             for(column=0; column<columns; ) {
  738.                 packetHeader=getc(fin);
  739.                 packetSize = 1 + (packetHeader & 0x7f);
  740.                 if (packetHeader & 0x80) {        // run-length packet
  741.                     switch (targa_header.pixel_size) {
  742.                         case 24:
  743.                                 blue = getc(fin);
  744.                                 green = getc(fin);
  745.                                 red = getc(fin);
  746.                                 alphabyte = 255;
  747.                                 break;
  748.                         case 32:
  749.                                 blue = getc(fin);
  750.                                 green = getc(fin);
  751.                                 red = getc(fin);
  752.                                 alphabyte = getc(fin);
  753.                                 break;
  754.                     }
  755.     
  756.                     for(j=0;j<packetSize;j++) {
  757.                         *pixbuf++=red;
  758.                         *pixbuf++=green;
  759.                         *pixbuf++=blue;
  760.                         *pixbuf++=alphabyte;
  761.                         column++;
  762.                         if (column==columns) { // run spans across rows
  763.                             column=0;
  764.                             if (row>0)
  765.                                 row--;
  766.                             else
  767.                                 goto breakOut;
  768.                             pixbuf = targa_rgba + row*columns*4;
  769.                         }
  770.                     }
  771.                 }
  772.                 else {                            // non run-length packet
  773.                     for(j=0;j<packetSize;j++) {
  774.                         switch (targa_header.pixel_size) {
  775.                             case 24:
  776.                                     blue = getc(fin);
  777.                                     green = getc(fin);
  778.                                     red = getc(fin);
  779.                                     *pixbuf++ = red;
  780.                                     *pixbuf++ = green;
  781.                                     *pixbuf++ = blue;
  782.                                     *pixbuf++ = 255;
  783.                                     break;
  784.                             case 32:
  785.                                     blue = getc(fin);
  786.                                     green = getc(fin);
  787.                                     red = getc(fin);
  788.                                     alphabyte = getc(fin);
  789.                                     *pixbuf++ = red;
  790.                                     *pixbuf++ = green;
  791.                                     *pixbuf++ = blue;
  792.                                     *pixbuf++ = alphabyte;
  793.                                     break;
  794.                         }
  795.                         column++;
  796.                         if (column==columns) { // pixel packet run spans across rows
  797.                             column=0;
  798.                             if (row>0)
  799.                                 row--;
  800.                             else
  801.                                 goto breakOut;
  802.                             pixbuf = targa_rgba + row*columns*4;
  803.                         }                        
  804.                     }
  805.                 }
  806.             }
  807.             breakOut:;
  808.         }
  809.     }
  810.     
  811.     fclose(fin);
  812. }
  813.